//
//  FuncViewController.swift
//  test_swift
//
//  Created by fangyuan ding on 2021/5/31.
//函数式编程

import UIKit
struct Student {
    let name: String
    let age: Int
    let score: Int
}
var students = [
    Student(name: "Calista", age: 18, score: 85),
    Student(name: "Griselda", age: 20, score: 88),
    Student(name: "Annabelle", age: 24, score: 92),
    Student(name: "Polly", age: 22, score: 93),
    Student(name: "Maud", age: 16, score: 95),
]
enum FilterType {
    case ageGreaterThan20
    case scoreGreaterThan90
    case ageGreaterThan20AndScoreGreaterThan90
}
class FuncViewController: UIViewController {

 
    override func viewDidLoad() {
        super.viewDidLoad()
        //在函数式编程中，函数是一等公民，不再把函数想象成一个处理过程，而是把它当作一个对象或者变量来对待。
        //所谓的高阶函数，就是把函数作为函数参数的函数
        //map
        print(sortedNamesWithMap(for: students))
//        ["Annabelle", "Calista", "Griselda", "Maud", "Polly"]
        //flilter
        let sortedNames = students.quickSorted().map{ $0.name }
        print(sortedNames)
        //在Swift中的Collection类型，都有一个reduce(_:)方法，它接受一个函数作为参数，其目的是对原集合中的元素进行合并，因此reduce(_:)的输出结果也是一个数值。
        /// 筛选 age > 20
        print(students.filter{ $0.age > 20}.map{ $0.name })

        /// 筛选 score > 90
        print(students.filter{ $0.score > 90}.map{ $0.name })

        /// 筛选 age > 20 && score > 90
        print(students.filter{ $0.age > 20 && $0.score > 90 }.map{ $0.name })
        
        
        print(filter(for: .ageGreaterThan20)(students))
        print(filter(for: .scoreGreaterThan90)(students))
        print(filter(for: .ageGreaterThan20AndScoreGreaterThan90)(students))
        //年龄小于18岁
        print(studentsWithAgeUnder(18, from: students))

        
      
    }
    
    func sortedNamesWithMap(for students: [Student]) -> [String] {
        var sortedStudents = students
        var current: Student

        for i in (0..<sortedStudents.count) {
            current = students[i]
            for j in stride(from: i, to: -1, by: -1) {
                if current.name.localizedCompare(sortedStudents[j].name) == .orderedAscending {
                    sortedStudents.remove(at: j + 1)
                    sortedStudents.insert(current, at: j)
                }
            }
        }

            /// 新增内容
        let names = sortedStudents.map{ $0.name }

        return names
    }
    
    func filter(for filterType: FilterType) -> ([Student]) -> [String] {
        return { students in
            switch filterType {
            case .ageGreaterThan20:
                return students.filter{ $0.age > 20}.map{ $0.name }
            case .scoreGreaterThan90:
                return students.filter{ $0.score > 90}.map{ $0.name }
            case .ageGreaterThan20AndScoreGreaterThan90:
                return students.filter{ $0.age > 20 && $0.score > 90 }.map{ $0.name }
            }
        }
    }
    func studentsWithAgeUnder(_ age: Int, from students: [Student]) -> [Student] {
        return students.filter{ $0.age < age }
    }

}
extension Array where Element: Comparable {
    func quickSorted() -> [Element] {
        if self.count > 1 {
            let (pivot, remaining) = (self[0], dropFirst())
            let lhs = remaining.filter{ $0 <= pivot}
            let rhs = remaining.filter{ $0 > pivot}
            return lhs.quickSorted() + [pivot] + rhs.quickSorted()
        }
        return self
    }
}
extension Student: Comparable {
    static func < (lhs: Student, rhs: Student) -> Bool {
        lhs.name < rhs.name
    }

    static func == (lhs: Student, rhs: Student) -> Bool {
        lhs.name == rhs.name
    }
}
